package com.atguigu.gulimall.order.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.atguigu.common.constant.OrderConstant;
import com.atguigu.common.exception.NoStockException;
import com.atguigu.common.to.SkuHasStockTo;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;
import com.atguigu.common.utils.R;
import com.atguigu.common.vo.MemberResponseVo;
import com.atguigu.common.vo.mq.OrderTo;
import com.atguigu.common.vo.mq.SecKillOrderTo;
import com.atguigu.gulimall.order.dao.OrderDao;
import com.atguigu.gulimall.order.entity.OrderEntity;
import com.atguigu.gulimall.order.entity.OrderItemEntity;
import com.atguigu.gulimall.order.entity.PaymentInfoEntity;
import com.atguigu.gulimall.order.enume.OrderStatusEnum;
import com.atguigu.gulimall.order.feign.CartFeignService;
import com.atguigu.gulimall.order.feign.MemberFeignService;
import com.atguigu.gulimall.order.feign.ProductFeignService;
import com.atguigu.gulimall.order.feign.WareFeignService;
import com.atguigu.gulimall.order.interceptor.LoginUserInterceptor;
import com.atguigu.gulimall.order.service.OrderItemService;
import com.atguigu.gulimall.order.service.OrderService;
import com.atguigu.gulimall.order.service.PaymentInfoService;
import com.atguigu.gulimall.order.to.OrderCreateTo;
import com.atguigu.gulimall.order.vo.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


@Service("orderService")
public class OrderServiceImpl extends ServiceImpl<OrderDao, OrderEntity> implements OrderService {
    // 使用 ThreadLocal 实现线程共享数据
    private ThreadLocal<OrderSubmitVo> submitVoThreadLocal = new ThreadLocal<>();

    @Resource
    private MemberFeignService memberFeignService;
    @Resource
    private CartFeignService cartFeignService;
    @Resource
    private ThreadPoolExecutor threadPoolExecutor;
    @Resource
    private WareFeignService wareFeignService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private ProductFeignService productFeignService;
    @Resource
    private OrderItemService orderItemService;
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private PaymentInfoService paymentInfoService;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<OrderEntity> page = this.page(
                new Query<OrderEntity>().getPage(params),
                new QueryWrapper<OrderEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public OrderConfirmVo confirmOrder() throws ExecutionException, InterruptedException {
        OrderConfirmVo confirmVo = new OrderConfirmVo();

        // 获取当前登录用户
        MemberResponseVo memberResponseVo = LoginUserInterceptor.loginUser.get();

        // 通过RequestContextHolder获取与当前线程绑定的RequestAttributes对象，该对象包含了当前HTTP请求的上下文信息，如请求参数、头部信息等
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

        CompletableFuture<Void> getAddressesFuture = CompletableFuture.runAsync(() -> {
            // 设置当前线程的RequestAttributes对象
            RequestContextHolder.setRequestAttributes(requestAttributes);
            // 远程调用 member 服务，获取当前用户的收货地址列表
            List<MemberAddressVo> addressVos = new ArrayList<>();
            R r = memberFeignService.getAddresses(memberResponseVo.getId());
            if (r.getCode() == 0) {
                Object data = r.get("data");
                addressVos = JSONUtil.toList(JSONUtil.toJsonStr(data), MemberAddressVo.class);
            }
            confirmVo.setAddress(addressVos);
        }, threadPoolExecutor);

        CompletableFuture<Void> getCartItemsFuture = CompletableFuture.runAsync(() -> {
            // 设置当前线程的RequestAttributes对象
            RequestContextHolder.setRequestAttributes(requestAttributes);
            // 远程调用 cart 服务，获取当前用户的购物车选中的购物项
            List<OrderItemVo> items = cartFeignService.getCurrentUserCheckedItems();
            confirmVo.setItems(items);
        }, threadPoolExecutor).thenRunAsync(() -> {
            List<Long> skuIds = confirmVo.getItems().stream().map(OrderItemVo::getSkuId).collect(Collectors.toList());
            R r = wareFeignService.getSkusHasStock(skuIds);
            if (r.getCode() == 0) {
                Object data = r.get("data");
                List<SkuHasStockTo> skuHasStockTos = JSONUtil.toList(JSONUtil.toJsonStr(data), SkuHasStockTo.class);
                if (CollectionUtil.isNotEmpty(skuHasStockTos)) {
                    Map<Long, Boolean> map = skuHasStockTos.stream().collect(Collectors.toMap(SkuHasStockTo::getSkuId, SkuHasStockTo::getHasStock));
                    confirmVo.setStocks(map);
                }
            }
        });

        // 获取当前用户积分
        confirmVo.setIntegration(memberResponseVo.getIntegration());
        // 剩余两个属性：订单总额 total、应付价格 payPrice 通过自定义 Getter 方法计算得到

        // 设置订单令牌，防止重复提交订单
        String token = UUID.randomUUID().toString().replace("-", "");
        confirmVo.setOrderToken(token);
        stringRedisTemplate.opsForValue().set(OrderConstant.USER_ORDER_TOKEN_PREFIX + memberResponseVo.getId(), token, 30, TimeUnit.MINUTES);

        CompletableFuture.allOf(getAddressesFuture, getCartItemsFuture).get();
        return confirmVo;
    }

    // @GlobalTransactional
    @Transactional
    @Override
    public SubmitOrderResponseVo submitOrder(OrderSubmitVo submitVo) {
        // 将提交订单的参数保存到 ThreadLocal 中
        submitVoThreadLocal.set(submitVo);
        SubmitOrderResponseVo responseVo = new SubmitOrderResponseVo();
        responseVo.setCode(0);
        // 当前登录用户信息
        MemberResponseVo memberResponseVo = LoginUserInterceptor.loginUser.get();
        // 1. 验证令牌
        /*// 从 Redis 中获取令牌
        String redisToken = stringRedisTemplate.opsForValue().get(OrderConstant.USER_ORDER_TOKEN_PREFIX + memberResponseVo.getId());
        if (!StringUtils.isEmpty(submitVo.getOrderToken()) && submitVo.getOrderToken().equals(redisToken)) {
            // 令牌验证通过，删除令牌
            stringRedisTemplate.delete(OrderConstant.USER_ORDER_TOKEN_PREFIX + memberResponseVo.getId());
        } else {
            // 令牌验证失败，返回错误信息
        }*/
        // 使用 Lua 脚本保证获取令牌、校验令牌、删除令牌的原子性操作
        // 0 校验失败，1 校验成功、删除令牌
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        Long result = stringRedisTemplate.execute(new DefaultRedisScript<Long>(script, Long.class), Arrays.asList(OrderConstant.USER_ORDER_TOKEN_PREFIX + memberResponseVo.getId()), submitVo.getOrderToken());
        if (result == 0L) {
            // 令牌验证失败
            responseVo.setCode(1);
            return responseVo;
        } else {
            // 令牌验证成功
            // 1. 创建订单、订单项等信息
            OrderCreateTo orderCreateTo = createOrder();
            // 2. 验价
            // 后台服务器端计算得到的订单应付金额
            BigDecimal payAmount = orderCreateTo.getOrder().getPayAmount();
            // 前端客户端传入的订单应付金额，可能省略了小数点两位后的金额
            BigDecimal payPrice = submitVo.getPayPrice();
            if (Math.abs(payAmount.subtract(payPrice).doubleValue()) < 0.01) {
                // 订单价格验证通过
                // 3. 保存订单数据到数据库
                saveOrder(orderCreateTo);
                // 4. 远程调用 ware 服务，锁定库存。如果出现异常，回滚订单数据
                // 锁定库存需要传给 ware 服务的数据：订单编号、订单项的 skuId、skuName、购买数量
                WareSkuLockVo wareSkuLockVo = new WareSkuLockVo();
                wareSkuLockVo.setOrderSn(orderCreateTo.getOrder().getOrderSn());
                List<OrderItemVo> orderItemVoList = orderCreateTo.getOrderItems().stream().map(item -> {
                    OrderItemVo orderItemVo = new OrderItemVo();
                    orderItemVo.setSkuId(item.getSkuId());
                    orderItemVo.setCount(item.getSkuQuantity());
                    orderItemVo.setTitle(item.getSkuName());
                    return orderItemVo;
                }).collect(Collectors.toList());
                wareSkuLockVo.setLocks(orderItemVoList);
                // 为了保证高并发，不使用 Seata 的 AT 模式实现分布式事务
                // 如果库存锁定失败，库存服务自行回滚
                R r = wareFeignService.orderLockStock(wareSkuLockVo);
                if (r.getCode() == 0) {
                    // 远程调用成功，库存锁定成功
                    responseVo.setOrder(orderCreateTo.getOrder());

                    // 模拟 order 服务远程调用 member 服务，扣减积分，出现异常
                    // int i = 1 / 0;

                    // 订单创建成功，发送消息到 MQ
                    rabbitTemplate.convertAndSend(OrderConstant.ORDER_EVENT_EXCHANGE, OrderConstant.ORDER_CREATE_ORDER_ROUTING_KEY, orderCreateTo.getOrder());

                    return responseVo;
                } else {
                    // 远程调用失败，库存锁定失败，订单回滚
                    throw new NoStockException((String) r.get("msg"));
                    // responseVo.setCode(3);
                    // return responseVo;
                }
            } else {
                // 订单价格验证失败
                responseVo.setCode(2);
                return responseVo;
            }
        }
    }



    /**
     * 保存订单数据到数据库
     * @param orderCreateTo
     */
    private void saveOrder(OrderCreateTo orderCreateTo) {
        // 保存订单
        OrderEntity orderEntity = orderCreateTo.getOrder();
        this.save(orderEntity);
        // 批量保存订单项
        List<OrderItemEntity> orderItemList = orderCreateTo.getOrderItems();
        orderItemService.saveBatch(orderItemList);
    }

    /**
     * 创建订单
     * @return
     */
    private OrderCreateTo createOrder() {
        OrderCreateTo orderCreateTo = new OrderCreateTo();
        // 1. 生成订单号
        // IdWorker 是 MyBatis-Plus 提供的分布式 ID 生成器，可以生成全局唯一 ID
        String orderSn = IdWorker.getTimeId();

        // 2. 构建订单
        OrderEntity orderEntity = buildOrder(orderSn);
        orderCreateTo.setOrder(orderEntity);

        // 3. 获取所有订单项数据
        List<OrderItemEntity> orderItemList = buildOrderItemList(orderSn);
        orderCreateTo.setOrderItems(orderItemList);

        // 4. 计算订单总额、优惠、积分、成长值等信息
        computePrice(orderEntity, orderItemList);

        // 5. 封装订单运费、订单应付总额
        orderCreateTo.setFare(orderEntity.getFreightAmount());
        orderCreateTo.setPayPrice(orderEntity.getPayAmount());
        return orderCreateTo;
    }

    /**
     * 计算订单总额、优惠、积分、成长值等信息
     * @param orderEntity
     * @param orderItemList
     */
    private void computePrice(OrderEntity orderEntity, List<OrderItemEntity> orderItemList) {
        BigDecimal orderTotalAmount = BigDecimal.ZERO;
        BigDecimal orderPromotionAmount = BigDecimal.ZERO;
        BigDecimal orderIntegrationAmount = BigDecimal.ZERO;
        BigDecimal orderCouponAmount = BigDecimal.ZERO;
        Integer orderIntegration = 0;
        Integer orderGrowth = 0;
        for (OrderItemEntity orderItem : orderItemList) {
            orderTotalAmount = orderTotalAmount.add(orderItem.getRealAmount());
            orderPromotionAmount = orderPromotionAmount.add(orderItem.getPromotionAmount());
            orderIntegrationAmount = orderIntegrationAmount.add(orderItem.getIntegrationAmount());
            orderCouponAmount = orderCouponAmount.add(orderItem.getCouponAmount());
            orderIntegration += orderItem.getGiftIntegration();
            orderGrowth += orderItem.getGiftGrowth();
        }
        // 设置订单总额
        orderEntity.setTotalAmount(orderTotalAmount);
        // 设置订单应付总额 = 订单总额 + 运费
        orderEntity.setPayAmount(orderTotalAmount.add(orderEntity.getFreightAmount()));
        // 设置订单促销优化金额
        orderEntity.setPromotionAmount(orderPromotionAmount);
        // 设置订单积分抵扣金额
        orderEntity.setIntegrationAmount(orderIntegrationAmount);
        // 设置订单优惠券抵扣金额
        orderEntity.setCouponAmount(orderCouponAmount);
        // 设置订单积分
        orderEntity.setIntegration(orderIntegration);
        // 设置订单成长值
        orderEntity.setGrowth(orderGrowth);
    }

    /**
     * 构建订单
     * @param orderSn
     */
    private OrderEntity buildOrder(String orderSn) {
        OrderEntity orderEntity = new OrderEntity();
        // 设置会员 ID
        MemberResponseVo memberResponseVo = LoginUserInterceptor.loginUser.get();
        orderEntity.setMemberId(memberResponseVo.getId());
        // 设置订单编号
        orderEntity.setOrderSn(orderSn);
        // 远程调用 ware 服务，根据收货地址 ID 获取地址详情和运费
        OrderSubmitVo submitVo = submitVoThreadLocal.get();
        R r = wareFeignService.getFare(submitVo.getAddrId());
        if (r.getCode() == 0) {
            Object data = r.get("data");
            FareVo fareVo = JSONUtil.toBean(JSONUtil.toJsonStr(data), FareVo.class);
            // 设置订单运费金额
            orderEntity.setFreightAmount(fareVo.getFare());
            // 设置收货人信息
            orderEntity.setReceiverProvince(fareVo.getAddress().getProvince());
            orderEntity.setReceiverCity(fareVo.getAddress().getCity());
            orderEntity.setReceiverRegion(fareVo.getAddress().getRegion());
            orderEntity.setReceiverDetailAddress(fareVo.getAddress().getDetailAddress());
            orderEntity.setReceiverPostCode(fareVo.getAddress().getPostCode());
            orderEntity.setReceiverPhone(fareVo.getAddress().getPhone());
            orderEntity.setReceiverName(fareVo.getAddress().getName());
        }
        // 设置订单状态信息
        orderEntity.setStatus(OrderStatusEnum.CREATE_NEW.getCode());
        // 设置订单自动确认时间，默认为 7 天
        orderEntity.setAutoConfirmDay(7);
        // 设置订单的删除状态 0 未删除，1 已删除
        orderEntity.setDeleteStatus(0);
        // 设置订单修改时间
        orderEntity.setModifyTime(new Date());
        return orderEntity;
    }

    /**
     * 根据购物车选中的购物项列表构建订单项列表
     * @return
     */
    private List<OrderItemEntity> buildOrderItemList(String orderSn) {
        List<OrderItemVo> currentUserCheckedItems = cartFeignService.getCurrentUserCheckedItems();
        List<OrderItemEntity> orderItemList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(currentUserCheckedItems)) {
            orderItemList = currentUserCheckedItems.stream().map(item -> {
                OrderItemEntity orderItem = buildOrderItem(item);
                orderItem.setOrderSn(orderSn);
                return orderItem;
            }).collect(Collectors.toList());
        }
        return orderItemList;
    }

    /**
     * 根据购物车选中的购物项构建订单项
     * @param cartItem 购物车选中的购物项
     * @return
     */
    private OrderItemEntity buildOrderItem(OrderItemVo cartItem) {
        OrderItemEntity orderItem = new OrderItemEntity();
        // 1. 订单信息：订单号（已完成）
        // 2. 商品 SPU 信息
        R r = productFeignService.getSpuInfoBySkuId(cartItem.getSkuId());
        if (r.getCode() == 0) {
            Object data = r.get("data");
            SpuInfoVo spuInfoVo = JSONUtil.toBean(JSONUtil.toJsonStr(data), SpuInfoVo.class);
            orderItem.setSpuId(spuInfoVo.getId());
            orderItem.setSpuBrand(spuInfoVo.getBrandId().toString());
            orderItem.setSpuName(spuInfoVo.getSpuName());
            orderItem.setCategoryId(spuInfoVo.getCatalogId());
        }
        // 3. 商品 SKU 信息
        orderItem.setSkuId(cartItem.getSkuId());
        orderItem.setSkuName(cartItem.getTitle());
        orderItem.setSkuPic(cartItem.getImage());
        orderItem.setSkuPrice(cartItem.getPrice());
        orderItem.setSkuQuantity(cartItem.getCount());
        String skuAttr = StringUtils.collectionToDelimitedString(cartItem.getSkuAttrs(), ";");
        orderItem.setSkuAttrsVals(skuAttr);
        // 4. 商品优惠信息（未实现）
        // 5. 商品积分信息
        orderItem.setGiftGrowth(cartItem.getPrice().multiply(new BigDecimal(cartItem.getCount())).intValue());
        orderItem.setGiftIntegration(cartItem.getPrice().multiply(new BigDecimal(cartItem.getCount())).intValue());
        // 6. 设置订单项的价格信息
        orderItem.setPromotionAmount(BigDecimal.ZERO);
        orderItem.setCouponAmount(BigDecimal.ZERO);
        orderItem.setIntegrationAmount(BigDecimal.ZERO);
        BigDecimal originPrice = orderItem.getSkuPrice().multiply(new BigDecimal(orderItem.getSkuQuantity()));
        BigDecimal realAmount = originPrice.subtract(orderItem.getPromotionAmount()).subtract(orderItem.getCouponAmount()).subtract(orderItem.getIntegrationAmount());
        orderItem.setRealAmount(realAmount);

        return orderItem;
    }

    @Override
    public OrderEntity getOrderByOrderSn(String orderSn) {
        return this.getOne(new LambdaQueryWrapper<OrderEntity>().eq(OrderEntity::getOrderSn, orderSn));
    }

    /**
     * 关闭订单
     * @param orderEntity
     */
    @Override
    public void closeOrder(OrderEntity orderEntity) {
        // 查询当前订单状态
        OrderEntity orderDb = this.getById(orderEntity.getId());
        if (orderDb.getStatus().equals(OrderStatusEnum.CREATE_NEW.getCode())) {
            // 当前订单属于超时未支付订单，需要关单
            orderDb.setStatus(OrderStatusEnum.CANCLED.getCode());
            this.updateById(orderDb);
            // 发送消息给 MQ，通知 ware 服务检查这个订单的库存是否需要解锁
            OrderTo orderTo = new OrderTo();
            BeanUtils.copyProperties(orderDb, orderTo);
            rabbitTemplate.convertAndSend("order-event-exchange", "order.release.other", orderTo);
        }
    }

    /**
     * 获取当前订单的支付信息
     * @param orderSn
     * @return
     */
    @Override
    public PayVo getOrderPayInfo(String orderSn) {
        PayVo payVo = new PayVo();
        OrderEntity order = this.getOrderByOrderSn(orderSn);
        if (order != null) {
            BigDecimal payAmount = order.getPayAmount();
            // 支付宝能接受的金额是两位小数，如果两位后不为零，向上进一位取值，比如 1.1234，则取 1.13
            BigDecimal bigDecimal = payAmount.setScale(2, RoundingMode.UP);
            payVo.setTotal_amount(bigDecimal.toString());

            payVo.setOut_trade_no(order.getOrderSn());

            // 订单名称，这里使用订单中购买的第一个商品的标题
            List<OrderItemEntity> orderItemList = orderItemService.list(new LambdaQueryWrapper<OrderItemEntity>().eq(OrderItemEntity::getOrderSn, orderSn));
            OrderItemEntity orderItem = orderItemList.get(0);
            payVo.setSubject(orderItem.getSkuName());

            // 订单备注，这里设置为订单中购买的第一个商品的销售属性
            payVo.setBody(orderItem.getSkuAttrsVals());
        }
        return payVo;
    }

    @Override
    public PageUtils getOrderListWithOrderItems(Map<String, Object> params) {
        // 通过登录拦截器中的 ThreadLocal 获取当前用户登录信息
        MemberResponseVo memberResponseVo = LoginUserInterceptor.loginUser.get();
        // 会员id
        Long memberId = memberResponseVo.getId();
        // 分页查询当前用户的所有订单
        IPage<OrderEntity> page = this.page(new Query<OrderEntity>().getPage(params),
                new LambdaQueryWrapper<OrderEntity>().eq(OrderEntity::getMemberId, memberId).orderByDesc(OrderEntity::getCreateTime));
        // 为分页查询结果中的订单设置订单项数据
        List<OrderEntity> orderList = page.getRecords().stream().peek(order -> order.setOrderItems(orderItemService.list(new LambdaQueryWrapper<OrderItemEntity>().eq(OrderItemEntity::getOrderSn, order.getOrderSn())))).collect(Collectors.toList());

        page.setRecords(orderList);
        return new PageUtils(page);
    }

    /**
     * 处理支付宝的支付结果
     * @param vo
     * @return
     */
    @Override
    public String handlePayResult(PayAsyncVo vo) {
        // 保存交易流水，方便后续与支付宝对账和用户退款 order 服务数据库表 oms_payment_info
        PaymentInfoEntity paymentInfo = new PaymentInfoEntity();
        paymentInfo.setOrderSn(vo.getOut_trade_no());
        paymentInfo.setAlipayTradeNo(vo.getTrade_no());
        paymentInfo.setTotalAmount(new BigDecimal(vo.getTotal_amount()));
        paymentInfo.setSubject(vo.getSubject());
        paymentInfo.setPaymentStatus(vo.getTrade_status());
        paymentInfo.setCreateTime(vo.getGmt_create());
        paymentInfo.setCallbackTime(vo.getNotify_time());
        paymentInfoService.save(paymentInfo);

        // 修改订单状态
        // 在支付宝的业务通知中，只有交易通知状态为 TRADE_SUCCESS 或 TRADE_FINISHED 时，支付宝才会认定为买家付款成功。
        // 交易状态 TRADE_SUCCESS 的通知触发条件是商家开通的产品支持退款功能的前提下，买家付款成功。
        // 交易状态 TRADE_FINISHED 的通知触发条件是商家开通的产品不支持退款功能的前提下，买家付款成功；或者，商家开通的产品支持退款功能的前提下，交易已经成功并且已经超过可退款期限。
        if (vo.getTrade_status().equals("TRADE_SUCCESS") || vo.getTrade_status().equals("TRADE_FINISHED")) {
            // 修改订单状态为已支付
            String orderSn = vo.getOut_trade_no();
            this.updateOrderStatus(orderSn, OrderStatusEnum.PAYED.getCode());
        }
        // 商户系统收到支付宝通知后返回 success，支付宝就认为商户系统已经收到了支付成功的通知，不再发送通知
        return "success";
    }

    @Override
    public void updateOrderStatus(String orderSn, Integer code) {
        this.update(new LambdaUpdateWrapper<OrderEntity>().set(OrderEntity::getStatus, code).eq(OrderEntity::getOrderSn, orderSn));
    }

    /**
     * 创建秒杀订单
     * @param secKillOrderTo
     */
    @Override
    public void createSeckillOrder(SecKillOrderTo secKillOrderTo) {
        // 保存订单信息，可以仿照 createOrder 方法，远程调用其他微服务，逐一设置订单信息
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setOrderSn(secKillOrderTo.getOrderSn());
        orderEntity.setMemberId(secKillOrderTo.getMemberId());
        orderEntity.setCreateTime(new Date());
        orderEntity.setStatus(OrderStatusEnum.CREATE_NEW.getCode());
        orderEntity.setPayAmount(secKillOrderTo.getSeckillPrice().multiply(new BigDecimal(secKillOrderTo.getNum())));
        this.save(orderEntity);

        // 保存订单项信息，秒杀订单只会涉及一个订单项。可以仿照 buildOrderItemList 方法，远程调用其他微服务，逐一设置订单项信息
        OrderItemEntity orderItemEntity = new OrderItemEntity();
        orderItemEntity.setOrderSn(secKillOrderTo.getOrderSn());
        orderItemEntity.setRealAmount(secKillOrderTo.getSeckillPrice());
        orderItemEntity.setSkuQuantity(secKillOrderTo.getNum());
        orderItemService.save(orderItemEntity);
    }

}